/** 
 * Class Description:########
 * Date : 2017年6月4日 上午10:40:45
 * Auth : wanglei 
*/  

package com.thd.springboot.framework.utils;

import io.jsonwebtoken.*;
import io.jsonwebtoken.impl.DefaultClaims;

import java.util.Date;
import java.util.concurrent.TimeUnit;

public class MyJwtUtils {

	/**
	 * 签发jwt
	 * @param claims 主体
	 * @param key 签名key
	 * @return
	 */
	public static String sign(Claims claims,String key) {
		//jwt signatureAlgorithm
		SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
		// ------------------------------------- JWT 生成JWT ------------------------------------- //
		JwtBuilder builder = Jwts.builder()
				.setHeaderParam("typ","JWT")
				.setHeaderParam("alg","HS256")
				.setClaims(claims)
				.signWith(signatureAlgorithm,key);

		String jwtToken = builder.compact();
		return jwtToken;
	}

	/**
	 * 签发jwt
	 * @param claims 主体
	 * @param key 签名key
	 * @param expireDate 到期时间 , 以此参数为准，会自动设置到Claims中的有效期属性,如果是null则没有有效期
	 * @return
	 */
	public static String signByExpire(Claims claims,String key,Date expireDate) {
		claims.setExpiration(expireDate);
		return MyJwtUtils.sign(claims,key);
	}

	/**
	 * 签发jwt - 持续秒数
	 * @param claims 主体
	 * @param key 签名key
	 * @param duration 有效时间(以秒为单位)
	 * @return
	 */
	public static String signByDurationSecond(Claims claims,String key,Long duration) {
		Date durationDate = MyJwtUtils.delayDate(new Date(),duration);
		return MyJwtUtils.signByExpire(claims,key,durationDate);
	}

	/**
	 * 签发jwt - 持续分钟
	 * @param claims 主体
	 * @param key 签名key
	 * @param duration 有效时间(以分钟为单位)
	 * @return
	 */
	public static String signByDurationMinutes(Claims claims,String key,Long duration) {
		Date durationDate = MyJwtUtils.delayDate(new Date(),duration*60);
		return MyJwtUtils.signByExpire(claims,key,durationDate);
	}

	/**
	 * 签发jwt - 持续小时
	 * @param claims 主体
	 * @param key 签名key
	 * @param duration 有效时间(以小时为单位)
	 * @return
	 */
	public static String signByDurationHours(Claims claims,String key,Long duration) {
		Date durationDate = MyJwtUtils.delayDate(new Date(),duration*60*60);
		return MyJwtUtils.signByExpire(claims,key,durationDate);
	}



	public static Claims parse(String jwtToken,String key){
		Claims decodeClaims = Jwts.parser()
				.setSigningKey(key)
				.parseClaimsJws(jwtToken).getBody();
		return decodeClaims;
	}




	public static Date delayDate(Date date,Long second) {
		// 纳秒
		Long basicDate = date.getTime();
		Long unitTimes = second * 1000;// 转毫秒
		Long expiredTime = basicDate + unitTimes;
		return new Date(expiredTime);

	}
/*
	public static void main(String[] args) throws Exception{
//		Date d = MyJwtUtils.delayDate(new Date(),3600l);
//		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
//		System.out.println(sdf.format(d));


		System.out.println("======================== 签发jwt ==========================");
		Claims claims = new DefaultClaims();
		claims.setSubject("devil13th");
		String jwtToken = MyJwtUtils.signByDurationSecond(claims,"123456789",3l);
		System.out.println(jwtToken);

		System.out.println("======================== 正常解析 start ==========================");

		// =============== parse ================
		try{
			Claims claims2 = MyJwtUtils.parse(jwtToken,"12345678");
			System.out.println(claims2);
		}catch(Exception e){
//			e.printStackTrace();
			System.out.println("错误信息：");
			System.out.println(e.getMessage());
		}


		// =============== parse 测试key================
		System.out.println("======================== 测试key错误 ==========================");
		try{
			Claims claims1 = MyJwtUtils.parse(jwtToken,"87654321");
			System.out.println(claims1);
		}catch(SignatureException e){
			System.out.println("错误信息：");
			System.out.println("key 错误");
			System.out.println(e.getMessage());
		}

		System.out.println("======================== 测试有效期 ==========================");

		// =============== parse 测试有效期================
		try{

			// 睡3秒钟 让token过期
			Thread.sleep(4*1000);

			Claims claims2 = MyJwtUtils.parse(jwtToken,"12345678");
			System.out.println(claims2);
		}catch(Exception e){
//			e.printStackTrace();
			System.out.println("错误信息：");
			System.out.println(e.getMessage());
		}

	}
*/

}
